#include <iostream>
#include <unistd.h>
#include <cstdio>
#include <string>
#include <cstring>
#include <vector>
#include <pthread.h>

#define ID_NUM 64
#define CYC_CNT 5

//重命名函数指针
typedef void *(*func)(void *);

//创建线程的个数
const int num = 5;

//每个线程对应的执行流
void *routine1(void *args)
{
    std::string name = static_cast<char *>(args);

    for (int i = 0; i < CYC_CNT; i++)
    {
        sleep(1);
        std::cout << "我是一个下载的线程, 我的name: " << name << std::endl;
    }

    return nullptr;
}

void *routine2(void *args)
{
    std::string name = static_cast<char *>(args);

    for (int i = 0; i < CYC_CNT; i++)
    {
        sleep(1);
        std::cout << "我是一个上传的线程, 我的name: " << name << std::endl;
    }

    return nullptr;
}

void *routine3(void *args)
{
    std::string name = static_cast<char *>(args);

    for (int i = 0; i < CYC_CNT; i++)
    {
        sleep(1);
        std::cout << "我是一个调度的线程, 我的name: " << name << std::endl;
    }

    return nullptr;
}

void *routine4(void *args)
{
    std::string name = static_cast<char *>(args);

    for (int i = 0; i < CYC_CNT; i++)
    {
        sleep(1);
        std::cout << "我是一个刷新的线程, 我的name: " << name << std::endl;
    }

    return nullptr;
}

void *routine5(void *args)
{
    std::string name = static_cast<char *>(args);

    for (int i = 0; i < CYC_CNT; i++)
    {
        sleep(1);
        std::cout << "我是一个计算的线程, 我的name: " << name << std::endl;
    }

    return nullptr;
}

int main()
{
    // 创建管理多个线程的容器
    std::vector<pthread_t> v;

    //函数指针数组，用来管理线程方法
    func routines[] = {routine1, routine2, routine3, routine4, routine5};
    
    // 创建指定个数的线程
    for (int i = 0; i < num; i++)
    {
        // 如果采用char id[64]的方式来记录线程名字，会出现覆盖的情况
        // char id[64];
        // 正确方法：每个线程都有对应独立的堆空间上的数据（线程名字）
        pthread_t tid;
        char *id = new char[ID_NUM];
        snprintf(id, ID_NUM, "thread-%d", i);
        int n = pthread_create(&tid, nullptr, routines[i], (void *)id);
        (void)n;
        v.push_back(tid);
    }

    // 循环回收线程
    for (int i = 0; i < num; i++)
    {
        int n = pthread_join(v[i], nullptr);
        (void)n;
        std::cout << "回收线程成功！" << std::endl;
    }
    return 0;
}